package com.main.dao;

import java.util.Collections;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.generico.base.BaseDaoImpl;
import com.generico.exception.AsiWebException;
import com.main.cliente.dto.SgiPersona;
import com.main.java.CtgDepartamento;
import com.web.util.GenericoUtil;

@Repository
public class SgiPersonaDaoImpl extends BaseDaoImpl implements SgiPersonaDao{
	
	@Autowired
	private SessionFactory sessionFactory;
	
	private Session openSession() {
		return sessionFactory.getCurrentSession();
	}
	
	public void savePersona (SgiPersona sgiPersona) throws AsiWebException {
		save(sgiPersona);
	}
	
	public void mergePersona (SgiPersona sgiPersona) throws AsiWebException {
		merge(sgiPersona);
	}
	
	@SuppressWarnings("unchecked")
	public List<Object[]> busquedaDepto(){
		Criteria criteria = openSession().getSessionFactory().getCurrentSession().createCriteria(CtgDepartamento.class);
		criteria.setProjection(
				Projections.projectionList().
				add(Projections.property("catalogoDepartamentoId")).
				add(Projections.property("catalogoDepartamentoNombre")));

		criteria.addOrder(Order.asc("catalogoDepartamentoId"));
		criteria.addOrder(Order.asc("catalogoDepartamentoNombre"));
		try{
			return (List<Object[]>) findByCriteria(criteria);
		}catch (Exception e) {
			logger.error(e, e);
			return Collections.emptyList();
		}
	}
	
	@SuppressWarnings("unchecked")
	public SgiPersona obtenerPersona(Long id) throws Exception{
		try {
			Criteria criteria = openSession().getSessionFactory().getCurrentSession().createCriteria(SgiPersona.class);
			criteria.add(Restrictions.eq("user.id", id));
			List<SgiPersona> list = (List<SgiPersona>) findByCriteria(criteria);
			if(!GenericoUtil.isEmptyList(list)) return list.get(0);
			return null;
		} catch (AsiWebException e) {
			logger.error(e, e);
			throw e;
		} catch (Exception e) {
			logger.error(e, e);
			throw new AsiWebException("Problemas al tratar de obtener la informaci\u00F3n de Persona por su Id");
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<Object[]> obtenerTodosLosDatosDeEmpleado() throws AsiWebException {
		Criteria criterias = openSession().getSessionFactory().getCurrentSession().createCriteria(SgiPersona.class);
		criterias.createAlias("user", "user");
		criterias.createAlias("user.ctgSucursal", "ctgSucursales");
		criterias.createAlias("ctgSucursales.ctgSubTipoSucursal", "ctgSubTipoSucursal");
		criterias.createAlias("ctgSubTipoSucursal.ctgTipoSucursal", "ctgTipoSucursal");
		criterias.createAlias("ctgmunicipio", "ctgmunicipio");
		criterias.createAlias("ctgDepartamento", "ctgDepartamento");
		
		
		criterias.setProjection(Projections.distinct(
				Projections.projectionList().
					add(Projections.property("user.id")).
					add(Projections.property("user.login")).
					add(Projections.property("user.password")).
					add(Projections.property("user.usuarioCambiarClave")).
					add(Projections.property("user.usuarioActivo")).
					add(Projections.property("PersonaPrimerNombre")).
					add(Projections.property("PersonaSegundoNombre")).
					add(Projections.property("PersonaPrimerApellido")).
					add(Projections.property("PersonaSegundoApellido")).
					add(Projections.property("personaEmail")).
					add(Projections.property("personaDocumento1")).
					add(Projections.property("personaDocumento2")).
					add(Projections.property("personaDocumento3")).
					add(Projections.property("personaDocumento4")).
					add(Projections.property("personaTelefono1")).
					add(Projections.property("personaTelefono2")).
					add(Projections.property("personaTelefono3")).
					add(Projections.property("ctgSucursales.ctgSucursalId")).
					add(Projections.property("ctgSucursales.ctgSucursalNombre")).
					add(Projections.property("ctgSubTipoSucursal.ctgSubTipoSucursalId")).
					add(Projections.property("ctgTipoSucursal.ctgTipoSucursalId")).
					add(Projections.property("personaDireccion")).
					add(Projections.property("ctgmunicipio.catalogoMunicipioId")).
					add(Projections.property("ctgDepartamento.catalogoDepartamentoId")).
					add(Projections.property("sgiPersonaId"))
//					add(Projections.property("ctgTipoDocumento.ctgCatalogoId"))
				));
		criterias.add(Restrictions.ne("user.id", 0L));
		criterias.addOrder(Order.asc("user.login"));

		return (List<Object[]>) findByCriteria(criterias);
	}
	
	public SgiPersona encontrarPersonaPorId(Long personaId) throws AsiWebException {
		SgiPersona persona = new SgiPersona();
		persona = (SgiPersona) findById(SgiPersona.class, personaId);
		return persona;	
	}
	
	@SuppressWarnings("unchecked")
	public SgiPersona obtenerPersonaPorUsuario(String user) throws Exception{
		try {
			Criteria criteria = openSession().getSessionFactory().getCurrentSession().createCriteria(SgiPersona.class);
			criteria.createAlias("user", "user");
			criteria.add(Restrictions.eq("user.login", user));
			List<SgiPersona> list = (List<SgiPersona>) findByCriteria(criteria);
			if(!GenericoUtil.isEmptyList(list)) return list.get(0);
			return null;
		} catch (AsiWebException e) {
			logger.error(e, e);
			throw e;
		} catch (Exception e) {
			logger.error(e, e);
			throw new AsiWebException("Problemas al tratar de obtener la informaci\u00F3n de Persona por su usuario");
		}
	}
	
}
